<template>
  <div class="qr-generator">
    <div class="input-section">
      <label for="text-input">输入要生成二维码的内容：</label>
      <textarea
        id="text-input"
        v-model="inputText"
        placeholder="请输入文本、URL或任何内容..."
        rows="4"
        class="text-input"
      ></textarea>
    </div>

    <div class="options-section">
      <div class="option-item">
        <label for="size">尺寸：</label>
        <input
          id="size"
          type="range"
          v-model.number="size"
          min="100"
          max="500"
          step="10"
          class="slider"
        />
        <span class="value">{{ size }}px</span>
      </div>

      <div class="option-item">
        <label for="error-level">纠错级别：</label>
        <select id="error-level" v-model="errorCorrectionLevel" class="select">
          <option value="L">低 (L)</option>
          <option value="M">中 (M)</option>
          <option value="Q">较高 (Q)</option>
          <option value="H">高 (H)</option>
        </select>
      </div>

      <div class="option-item">
        <label>
          <input type="checkbox" v-model="margin" />
          包含边距
        </label>
      </div>
    </div>

    <div class="button-section">
      <button
        @click="generateQRCode"
        :disabled="!inputText"
        class="btn-primary"
      >
        生成二维码
      </button>
      <button
        @click="downloadQRCode"
        :disabled="!qrCodeUrl"
        class="btn-secondary"
      >
        下载二维码
      </button>
      <button @click="clearAll" class="btn-clear">清空</button>
    </div>

    <div v-if="loading" class="loading">生成中...</div>

    <div v-if="qrCodeUrl && !loading" class="qr-display">
      <img :src="qrCodeUrl" alt="二维码" class="qr-image" />
    </div>

    <div v-if="error" class="error">
      {{ error }}
    </div>
  </div>
</template>

<script setup>
import { ref } from "vue";
import QRCode from "qrcode";

const inputText = ref("");
const qrCodeUrl = ref("");
const loading = ref(false);
const error = ref("");
const size = ref(300);
const errorCorrectionLevel = ref("M");
const margin = ref(true);

const generateQRCode = async () => {
  if (!inputText.value.trim()) {
    error.value = "请输入内容";
    return;
  }

  loading.value = true;
  error.value = "";
  qrCodeUrl.value = "";

  try {
    const url = await QRCode.toDataURL(inputText.value, {
      width: size.value,
      margin: margin.value ? 2 : 0,
      errorCorrectionLevel: errorCorrectionLevel.value,
      color: {
        dark: "#000000",
        light: "#FFFFFF",
      },
    });
    qrCodeUrl.value = url;
  } catch (err) {
    error.value = "生成二维码失败：" + err.message;
    console.error(err);
  } finally {
    loading.value = false;
  }
};

const downloadQRCode = () => {
  if (!qrCodeUrl.value) return;

  const link = document.createElement("a");
  link.download = `qrcode-${Date.now()}.png`;
  link.href = qrCodeUrl.value;
  link.click();
};

const clearAll = () => {
  inputText.value = "";
  qrCodeUrl.value = "";
  error.value = "";
  size.value = 300;
  errorCorrectionLevel.value = "M";
  margin.value = true;
};
</script>

<style scoped>
.qr-generator {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.input-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

label {
  font-weight: 500;
  color: #555;
  font-size: 14px;
}

.text-input {
  width: 100%;
  padding: 12px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  resize: vertical;
  transition: border-color 0.3s;
}

.text-input:focus {
  outline: none;
  border-color: #667eea;
}

.options-section {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
}

.option-item {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.slider {
  flex: 1;
  min-width: 150px;
}

.value {
  min-width: 60px;
  font-weight: 500;
  color: #667eea;
}

.select {
  padding: 8px 12px;
  border: 2px solid #e0e0e0;
  border-radius: 6px;
  font-size: 14px;
  background: white;
  cursor: pointer;
  transition: border-color 0.3s;
}

.select:focus {
  outline: none;
  border-color: #667eea;
}

input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

.button-section {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

button {
  flex: 1;
  min-width: 120px;
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-secondary {
  background: #4caf50;
  color: white;
}

.btn-secondary:hover:not(:disabled) {
  background: #45a049;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(76, 175, 80, 0.4);
}

.btn-secondary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-clear {
  background: #f44336;
  color: white;
}

.btn-clear:hover {
  background: #da190b;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(244, 67, 54, 0.4);
}

.loading {
  text-align: center;
  padding: 20px;
  color: #667eea;
  font-weight: 500;
}

.qr-display {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
}

.qr-image {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.error {
  padding: 12px;
  background: #ffebee;
  color: #c62828;
  border-radius: 8px;
  border-left: 4px solid #c62828;
}
</style>
